/*  File Name	: Lock.h
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-3-22
 *  Description:
 */

#ifndef LOCK_H_
#define LOCK_H_

#include <pthread.h>
#include <iostream>
#include "Define.h"
#define DEBUG_LOCK(X) //if(DEBUG_SWITCH) {std::cout << X << std::endl;}

class Lock
{
public:
	Lock();
	virtual ~Lock();

	virtual int remove(void)=0;

	virtual int acquire(void)=0;

	virtual int acquire(int sec,int nsec=0)=0; //nsec毫微秒(时间单位，=十亿分之一(10⁻)秒)[略作ns]

	virtual int acquire_read(void)=0;

	virtual int acquire_write(void)=0;

	virtual int tryacquire(void)=0;

	virtual int tryacquire_read(void)=0;

	virtual int tryacquire_write(void)=0;

	virtual int release(void)=0;
};

class RecursiveThreadMutex_t
{
public:
	RecursiveThreadMutex_t();
	virtual ~RecursiveThreadMutex_t();

	pthread_mutex_t p_mutex_;
	pthread_t owner_id_;

private:
	RecursiveThreadMutex_t &operator=(const RecursiveThreadMutex_t &);
	 RecursiveThreadMutex_t( const RecursiveThreadMutex_t &);
};

class RecursiveThreadMutex:public Lock
{
public:
	RecursiveThreadMutex();
	virtual ~RecursiveThreadMutex();

	virtual int remove(void);

	virtual int acquire(void);

	//nsec毫微秒(时间单位，=十亿分之一(10⁻)秒)[略作ns]
	virtual int acquire(int sec,int nsec=0);

	virtual int acquire_read(void);

	virtual int acquire_write(void);

	virtual int tryacquire(void);

	virtual int tryacquire_read(void);

	virtual int tryacquire_write(void);

	virtual int release(void);

	virtual pthread_t get_thread_id(void);

	RecursiveThreadMutex_t &mutex(void);

protected:
	void set_thread_id(pthread_t t);

	RecursiveThreadMutex_t lock_;

private:
	RecursiveThreadMutex &operator= (const RecursiveThreadMutex &);
	RecursiveThreadMutex(const RecursiveThreadMutex &);
};

typedef RecursiveThreadMutex RT_MUTEX;

//////////////////////////lock guard//////////////////////////

template <class LockType>
class LockGuard
{
public:
	LockGuard(LockType &lock);

	virtual ~LockGuard();

	int acquire(void);

	int release(void);

	int remove(void);

	bool locked(void);

private:
	void operator= (LockGuard<LockType> &);

	LockGuard (const LockGuard<LockType> &);

	LockType *lock_;
	int owner_;
};

template <class LockType>
class WriteLockGuard:public LockGuard<LockType>
{
public:
	WriteLockGuard(LockType &lock);

	virtual ~WriteLockGuard();

	int acquire(void);

	int acquire_write(void);

	int release(void);

	int remove(void);
};

#define LockGuardReturn(MUTEX_TYPE,OBJ,LOCK,RETURN) \
	LockGuard<MUTEX_TYPE> OBJ(LOCK);\
	if(OBJ.locked()){} \
	else\
	{ \
		std::cout<<"======get lock error====="<<std::endl;\
		return RETURN;\
	}

template <class LockType>
LockGuard<LockType>::LockGuard(LockType &lock)
{
	this->lock_ = &lock;
	this->owner_ = -1;
	this->acquire();
}

template <class LockType>
LockGuard<LockType>::~LockGuard()
{
	this->release();
}

template <class LockType>
int LockGuard<LockType>::acquire(void)
{
	if(this->owner_==-1)
	{
		if(NULL!=this->lock_)
		{
			return (this->owner_ =this->lock_->acquire());
		}
#ifdef DEBUG
		std::cout<<"LockGuard<LockType>::acquire error lock_ is null"<<std::endl;
#endif
	}
	return this->owner_ ;
}

template <class LockType>
int LockGuard<LockType>::release(void)
{
	if(NULL==this->lock_)
	{
#ifdef DEBUG
		std::cout<<"LockGuard<LockType>::release error lock_ is null"<<std::endl;
#endif
		return -1;
	}
	return this->lock_->release();
}

template <class LockType>
bool LockGuard<LockType>::locked(void)
{
	return (this->owner_ !=-1);
}

template <class LockType>
int LockGuard<LockType>::remove(void)
{
	if(NULL==this->lock_)
	{
#ifdef DEBUG
		std::cout<<"LockGuard<LockType>::remove lock_ is null"<<std::endl;
#endif
		return -1;
	}
	return this->lock_->remove();
}

#endif /* LOCK_H_ */
